package bookstore.presentation;

import static java.lang.System.out;

import java.util.ArrayList;
import java.util.List;

import bookstore.dao.Cabinet;
import bookstore.dao.CabinetImpl;
import bookstore.domain.Book;
import bookstore.domain.CODE;
import bookstore.domain.MSG;
import bookstore.domain.Order;
import bookstore.service.Guest;
import bookstore.service.GuestImpl;
import bookstore.service.Host;
import bookstore.service.HostImpl;
import bookstore.util.In;

public class ShopImpl implements Shop {
	private Menu menu;
	private List<Book> shelf;
	private List<Order> orders;
	private Host host;
	private Guest guest;
	private Cabinet cabinet;  

	public ShopImpl() {		
		load();
		menu = new MenuImpl(this);
		host = new HostImpl(shelf, orders);
		guest = new GuestImpl(host);
		
	}
	
	public void play() {
		out.println(MSG.BOOKSTORE_OPEN);		
		do {
			menu.play();
		} while (!exit());
		save();
		out.println(MSG.BOOKSTORE_CLOSE);
	}	

	private void save(){
		cabinet.save(shelf,CODE.BOOKSHELF);
		cabinet.save(orders, CODE.ORDERS);
	}		
	
	@SuppressWarnings("unchecked")
	private void load(){
		cabinet = new CabinetImpl();
		shelf = (List<Book>)cabinet.load(CODE.BOOKSHELF);
		orders = (List<Order>)cabinet.load(CODE.ORDERS);
		if(shelf == null) shelf = new ArrayList<Book>();
		if(orders == null) orders = new ArrayList<Order>();
	}

	// ask if shut down.
	private boolean exit() {
		out.print(MSG.BOOKSTORE_CLOSE_ASK+"\n>> ");
		return In.nextLine().equalsIgnoreCase("y");
	}

	public boolean login(int who) {
		boolean isOK = false;
		String id = ""; 
		String pw = "";

		out.print(MSG.LOGIN_INFO_DETAIL[0]+": ");
		id = In.nextLine();
		out.print(MSG.LOGIN_INFO_DETAIL[1]+": ");
		pw = In.nextLine();

		switch (who) {
		case CODE.HOST:
			if (id == CODE.HOST_LOGIN_INFO && pw == CODE.HOST_LOGIN_INFO)
				isOK = true;
			break;
		case CODE.GUEST:
			if (id == CODE.GUEST_LOGIN_INFO && pw == CODE.GUEST_LOGIN_INFO) 
				isOK = true;
			break;
		}
		return isOK;
	}

	// call method.
	public void call(int procCode) {
		boolean isOK = false;

		switch (procCode) {			
			case CODE.HOST_STOCK_LIST: {
				List<Book> list = host.stockList();
				if (list != null && list.size() != 0) {
					for (Book book : list)
						out.println(book);
					isOK = true;
				}
				break;
			}
			case CODE.HOST_STOCK_ADD: {
				isOK = host.stockAdd();
				break;
			}
			case CODE.HOST_STOCK_MODIFY: {
				int code = In.nextCode();
				if (code > 0) {
					Book book = host.stockView(code);
					if (host.stockModify(book) != null)
						isOK = true;
				}
				break;
			}
			case CODE.HOST_STOCK_DEL: {
				int code = In.nextCode();
				if (code > 0) isOK = host.stockDel(code);
				break;
			}	
			case CODE.HOST_SELL_LIST: {
				List<Order> list = host.sellList();
				int total = 0;
				if (list != null && list.size() != 0) {
					for (Order order : list) {
						out.println(order);
						total += order.getStatus()!=CODE.ORDER_STATUS_CANCEL
								? order.getBook().getPrice():0;
					}
					out.println("Total: $" + total);
					isOK = true;
				}
				break;
			}
			case CODE.HOST_SELL_SEND: {
				int code = In.nextOrderCode();
				if (code > 0) isOK = host.sellSend(code);
				break;
			}
			case CODE.HOST_SELL_CANCEL: {
				int code = In.nextOrderCode();
				if (code > 0) isOK = host.sellCancel(code);
				break;
			}	
			
			case CODE.GUEST_BUY_LIST: {
				List<Book> list = guest.buyList();
				if (list != null && list.size() != 0) {
					for (Book book : list)
						out.println(book);
					isOK = true;
				}
				break;
			}
			case CODE.GUEST_BUY_BUY: {
				int code = In.nextCode();
				if (code > 0)
					isOK = guest.buy(code);
				break;
			}
			case CODE.GUEST_CART_LIST: {
				List<Book> list = guest.cartList();
				if (list != null && list.size() != 0) {
					for (Book book : list)
						out.println(book);
					isOK = true;
				}
				break;
			}
			case CODE.GUEST_CART_DEL: {
				int code = In.nextCode();
				if (code > 0) isOK = guest.cartDel(code);
				break;
			}
			case CODE.GUEST_CART_PAY:{
				isOK = guest.cartPay();
				break;
			}
		}
		
		out.println(isOK ? MSG.OK : MSG.FAIL);
	}
}
